package me.zhengjie.modules.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import me.zhengjie.config.enums.ExamTypeEnum;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.modules.system.domain.vo.TestExamInfoVo;
import me.zhengjie.modules.system.service.*;
import me.zhengjie.modules.system.service.dto.*;
import me.zhengjie.modules.web.domain.ExamListRequest;
import me.zhengjie.modules.web.service.IAtmrExamService;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 试题业务类
 */
@Service
public class AtmrExamServiceImpl implements IAtmrExamService {

    @Autowired
    private ExamTypeService examTypeService;

    @Autowired
    private AtmrService atmrService;

    @Autowired
    private AtmrExamTypeService atmrExamTypeService;

    @Autowired
    private ExamInfoService examInfoService;

    @Autowired
    ExamDatabaseService examDatabaseService;

    @Autowired
    RedisUtils redisUtils;

    @Override
    public TestExamInfoVo list(ExamListRequest request) {

        if(StringUtils.isNotEmpty(request.getTestUuid())){
            String json = (String)redisUtils.lGetIndex(request.getTestUuid(),request.getIndex());
            ExamInfoDto examPd = JSONUtil.toBean(json,ExamInfoDto.class);
            return TestExamInfoVo.builder()
                    .testUuid(request.getTestUuid())
                    .count(redisUtils.lSize(request.getTestUuid()))
                    .examIndex(request.getIndex())
                    .examInfoDtoList(Lists.newArrayList(examPd))
                    .build();
        }
        if (null == request.getAtmrId()){
            throw new WeChatException("参数不能为空");
        }
        AtmrDto atmrDto = atmrService.findById(request.getAtmrId());
        if (null == atmrDto || !atmrDto.getStatus().equals("0") || ObjectUtil.isEmpty(atmrDto.getExamDatabaseId())){
            throw new WeChatException("参数不合法");
        }

        Long examDatabaseId = atmrDto.getExamDatabaseId();
        if(ObjectUtil.isEmpty(examDatabaseId) || examDatabaseId <= 0){
            ExamDatabaseQueryCriteria databaseQueryCriteria = new ExamDatabaseQueryCriteria();
            databaseQueryCriteria.setAtmrExamTypeId(Long.valueOf(request.getAtmrId()));
            List<ExamDatabaseDto> examDatabaseDtoList =  examDatabaseService.queryAll(databaseQueryCriteria);
            if(CollectionUtils.isEmpty(examDatabaseDtoList)){
                throw new WeChatException("题库为空");
            } else if(examDatabaseDtoList.size() == 1){
                examDatabaseId = examDatabaseDtoList.get(0).getDatabaseId();
            } else {
                Random r = new Random();
                int index = r.nextInt()%examDatabaseDtoList.size();
                examDatabaseId = examDatabaseDtoList.get(index).getDatabaseId();
            }

        }

        ExamInfoQueryCriteria examInfoQueryCriteria = new ExamInfoQueryCriteria();
        examInfoQueryCriteria.setStatus("0");
        examInfoQueryCriteria.setExamDatabaseId(examDatabaseId);
        List<ExamInfoDto> examInfoDtos = examInfoService.queryAll(examInfoQueryCriteria);
        if (CollectionUtil.isEmpty(examInfoDtos)){
            throw new WeChatException("题目为空");
        }
        for(ExamInfoDto examPd : examInfoDtos) {
            if(StringUtils.isNotBlank(examPd.getChose())){
                String chose = examPd.getChose().replaceAll(",",";");
                String[] options = chose.split(";");
                examPd.setOptions(options);
            }
            if(StringUtils.isNotBlank(examPd.getScore())){
                String[] scores = examPd.getScore().split(";");
                examPd.setScores(scores);
            }
        }


        List<ExamInfoDto> allChildren = new ArrayList<>();
        for(ExamInfoDto examPd : examInfoDtos){
            List<ExamInfoDto> children = examInfoDtos.stream().filter(s -> s.getExamNo().startsWith(examPd.getExamNo()) && s.getExamNo().length() > examPd.getExamNo().length()).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(children)){
                continue;
            }
            examPd.setChildrenList(children);
            allChildren.addAll(children);
        }

        List<ExamInfoDto> shuffleList = examInfoDtos.stream().filter(s -> ExamTypeEnum.S.getCode().equals(s.getExamTypeId())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(shuffleList)){
            shuffleList = new ArrayList<>();
        }
        List<ExamInfoDto> noSingleList = examInfoDtos.stream().filter(s -> !ExamTypeEnum.S.getCode().equals(s.getExamTypeId())).collect(Collectors.toList());
        Collections.shuffle(noSingleList);
        shuffleList.addAll(noSingleList);

        String uuid = UUID.randomUUID().toString();
        Iterator<ExamInfoDto>  iterator = shuffleList.iterator();
        while (iterator.hasNext()){
            ExamInfoDto examInfoDto = iterator.next();
            if(allChildren.contains(examInfoDto)){
                iterator.remove();
                continue;
            }
            redisUtils.lSet(uuid, JSONUtil.toJsonStr(examInfoDto),24*60*60);
        }

        String json = (String) redisUtils.lGetIndex(uuid,0);
        ExamInfoDto examPd = JSONUtil.toBean(json,ExamInfoDto.class);
        return TestExamInfoVo.builder()
                .testUuid(uuid)
                .count(redisUtils.lSize(uuid))
                .examIndex(0)
                .examInfoDtoList(Lists.newArrayList(examPd))
                .build();
    }
}
